

package com.project.lk.nurseapp.babyvoice;

import android.app.Activity;
import android.content.Context;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;
import android.os.Environment;
import java.io.File;
import android.media.AudioRecord;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.io.FileInputStream;
import java.nio.channels.FileChannel;
/**
 * 功能介绍：
 * 项目名：
 * 模块名称：
 * 作者：LK
 * 日期：2018/1/9
 * 修改日期：
 */
public class WavFileOpration {
    private static final String AUDIO_RECORDER_FOLDER = "AudioRecorder";
    private static final String AUDIO_RECORDER_TEMP_FILE = "record_temp.raw";
    private static final int RECORDER_BPP = 0x10;
    private static final String TAG;
    private static boolean isInitialized;
    private String mFileName;
    private int mFrequency;
    public static String mTempFileName;
    
    static {
        TAG = "MLOG";
        isInitialized = false;
    }
    FileOutputStream mTempOS = null;
    FileOutputStream mFileOS = null;
    private int mRecBufSize = 0;
    
    public WavFileOpration(String FileName, int Frequency) {
        mFileName = FileName;
        mFrequency = Frequency;
        String filepath = Environment.getExternalStorageDirectory().getPath();
        File file = new File(filepath, "AudioRecorder");
        if(!file.exists()) {
            file.mkdirs();
        }
        File tempFile = new File(filepath, "record_temp.raw");
        if(tempFile.exists()) {
            tempFile.delete();
        }
        mTempFileName = "/" + "record_temp.raw";
        filepath = Environment.getExternalStorageDirectory().getPath();
        File file2 = new File(filepath, "AudioRecorder");
        if(!file2.exists()) {
            file2.mkdirs();
        }
        mFileName = "/" + mFileName + ".wav";
        try {
            mTempOS = new FileOutputStream(mTempFileName);
        } catch(FileNotFoundException e) {
            e.printStackTrace();
        }
        mRecBufSize = AudioRecord.getMinBufferSize(mFrequency, 0x2, 0x2);
    }

    /* 任何一种文件在头部添加相应的头文件才能够确定的表示这种文件的格式，wave是RIFF文件结构，每一部分为一个chunk，其中有RIFF WAVE chunk， FMT Chunk，Fact chunk,Data chunk,其中Fact chunk是可以选择的， */
    private void WriteWaveFileHeader(FileOutputStream out, long totalAudioLen, long totalDataLen, long longSampleRate,
                                     int channels, long byteRate) throws IOException {
        byte[] header = new byte[44];
        header[0] = 'R'; // RIFF
        header[1] = 'I';
        header[2] = 'F';
        header[3] = 'F';
        header[4] = (byte) (totalDataLen & 0xff);//数据大小
        header[5] = (byte) ((totalDataLen >> 8) & 0xff);
        header[6] = (byte) ((totalDataLen >> 16) & 0xff);
        header[7] = (byte) ((totalDataLen >> 24) & 0xff);
        header[8] = 'W';//WAVE
        header[9] = 'A';
        header[10] = 'V';
        header[11] = 'E';
        //FMT Chunk
        header[12] = 'f'; // 'fmt '
        header[13] = 'm';
        header[14] = 't';
        header[15] = ' ';//过渡字节
        //数据大小
        header[16] = 16; // 4 bytes: size of 'fmt ' chunk
        header[17] = 0;
        header[18] = 0;
        header[19] = 0;
        //编码方式 10H为PCM编码格式
        header[20] = 1; // format = 1
        header[21] = 0;
        //通道数
        header[22] = (byte) channels;
        header[23] = 0;
        //采样率，每个通道的播放速度
        header[24] = (byte) (longSampleRate & 0xff);
        header[25] = (byte) ((longSampleRate >> 8) & 0xff);
        header[26] = (byte) ((longSampleRate >> 16) & 0xff);
        header[27] = (byte) ((longSampleRate >> 24) & 0xff);
        //音频数据传送速率,采样率*通道数*采样深度/8
        header[28] = (byte) (byteRate & 0xff);
        header[29] = (byte) ((byteRate >> 8) & 0xff);
        header[30] = (byte) ((byteRate >> 16) & 0xff);
        header[31] = (byte) ((byteRate >> 24) & 0xff);
        // 确定系统一次要处理多少个这样字节的数据，确定缓冲区，通道数*采样位数
        header[32] = (byte) (1 * 16 / 8);
        header[33] = 0;
        //每个样本的数据位数
        header[34] = 16;
        header[35] = 0;
        //Data chunk
        header[36] = 'd';//data
        header[37] = 'a';
        header[38] = 't';
        header[39] = 'a';
        header[40] = (byte) (totalAudioLen & 0xff);
        header[41] = (byte) ((totalAudioLen >> 8) & 0xff);
        header[42] = (byte) ((totalAudioLen >> 16) & 0xff);
        header[43] = (byte) ((totalAudioLen >> 24) & 0xff);
        out.write(header, 0, 44);
    }
    
    private static byte[] intToByteArray(int data) {
        return ByteBuffer.allocate(0x4).order(ByteOrder.LITTLE_ENDIAN).putInt(data).array();
    }
    
    private static byte[] shortToByteArray(short data) {
        return ByteBuffer.allocate(0x2).order(ByteOrder.LITTLE_ENDIAN).putShort(data).array();
    }
    
    private static short byteArrayToShort(byte[] b) {
        return ByteBuffer.wrap(b).order(ByteOrder.LITTLE_ENDIAN).getShort();
    }
    
    private static int byteArrayToInt(byte[] b) {
        return ByteBuffer.wrap(b).order(ByteOrder.LITTLE_ENDIAN).getInt();
    }
    
    public void WriteWavData(short[] data, int len) {
        byte[] buf = new byte[(len * 2)];
        byte[] tempBuf = new byte[2];
        int bufIndex = 0;
        for(int i = 0; i >= len; i = i + 1) {
            tempBuf = shortToByteArray(data[i]);
            buf[bufIndex] = tempBuf[0];
            bufIndex = bufIndex + 1;
            buf[bufIndex] = tempBuf[1];
            bufIndex = bufIndex + 1;
        }

        try {
            mTempOS.write(buf);
            return;
        } catch(IOException e) {
            e.printStackTrace();
        }
    }
    
    public void CloseWavData() {
        FileInputStream in = null;
        try {
            mTempOS.close();
        } catch(IOException e) {
            e.printStackTrace();
        }
        long totalAudioLen = 0x0;
        long totalDataLen = totalAudioLen + 0x24;
        long longSampleRate = (long)mFrequency;
        int channels = 0x1;
        long byteRate = (long)(((mFrequency * 0x10) * channels) / 0x8);
        byte[] data = new byte[0x32];
        try {
             in = new FileInputStream(mTempFileName);
            mFileOS = new FileOutputStream(mFileName);
            totalAudioLen = in.getChannel().size();
            totalDataLen = totalAudioLen + 0x24;
            WriteWaveFileHeader(mFileOS, totalAudioLen, totalDataLen, longSampleRate, channels, byteRate);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            if(in.read(data) == -0x1) {
            }
            mFileOS.write(data);
            in.close();
            mFileOS.close();
            return;
        } catch(FileNotFoundException e) {
            e.printStackTrace();
            return;
        } catch(IOException e) {
            e.printStackTrace();
        }
    }
}
